﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace cc2530.Lib.device
{

    /// <summary>
    /// 环形缓冲区
    /// </summary>
    class RingBuf
    {
        class Buf
        {
            public int len;
            public byte[] data;

            public void SetBufSize(int BufSize)
            {
                data = new byte[BufSize];
            }
        }

        private Buf[] m_ring_buf;
        private int m_read_index;
        private int m_write_index;
        private int m_num_of_buf;
        private int m_buf_size;
        System.Object m_lock = new System.Object();

        public RingBuf(int NumOfBuf, int BufSize)
        {
            m_ring_buf = new Buf[NumOfBuf];
            m_num_of_buf = NumOfBuf;
            m_buf_size = BufSize;
            for (int i = 0; i < NumOfBuf; i++)
            {
                m_ring_buf[i] = new Buf();
                m_ring_buf[i].data = new byte[BufSize];
                //m_ring_buf[i].SetBufSize(BufSize);
                m_ring_buf[i].len = 0;
            }
            m_read_index = 0;
            m_write_index = 0;
        }

        private int AddIndex(int Index)
        {
            Index++;
            if (Index >= m_num_of_buf)
                Index = 0;
            return Index;
        }
        public bool IsFull()
        {
            return (AddIndex(m_write_index) == m_read_index);
        }
        public bool IsEmpty()
        {
            return (m_write_index == m_read_index);
        }
        public void WriteBuf(byte[] pBuf, int Len)
        {
            lock (m_lock)
            {
                if (this.IsFull())
                {
                    m_read_index = AddIndex(m_read_index);
                }
                if (Len > m_buf_size)
                    Len = m_buf_size;
                for (int i = 0; i < Len; ++i)
                {
                    m_ring_buf[m_write_index].data[i] = pBuf[i];
                }
                m_ring_buf[m_write_index].len = Len;
                m_write_index = AddIndex(m_write_index);
            }   
        }

        /// <summary>
        /// 读缓冲区 
        /// </summary>
        /// <param name="pBuf"></param>
        /// <param name="ReadSize"></param>
        /// <returns></returns>
        public int ReadBuf(byte[] pBuf, int ReadSize)
        {
            if (this.IsEmpty())
                return 0;
            lock (m_lock)
            {
                int Len = m_ring_buf[m_read_index].len;
                if (ReadSize > Len)
                    ReadSize = Len;
                for (int i = 0; i < ReadSize; i++)
                {
                    pBuf[i] = m_ring_buf[m_read_index].data[i];
                }
                m_ring_buf[m_read_index].len = 0;
                m_read_index = AddIndex(m_read_index);
            }
            return ReadSize;
        }

        /// <summary>
        /// 缓冲区数据长度
        /// </summary>
        /// <returns></returns>
        public int ReadBufLen() {
            return m_ring_buf[m_read_index].len;
        }
    
    }
}
